﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Graphics;

namespace ShevaEngine.Core.Modules.Graphics
{
    /// <summary>
    /// Draw call.
    /// </summary>
    public class IndexedPrimitivesDrawCall : DrawCall
    {
        /// <summary>Typ primitiva.</summary>
        public PrimitiveType PrimitiveType;
        /// <summary>The number of vertices used during a draw call.</summary>
        public int NumVertices;
        /// <summary>The number of primitives to render.</summary>
        public int PrimitiveCount;
        /// <summary>The location in the index array at which to start reading vertices.</summary>
        public int StartIndex;
        /// <summary>The offset (in vertices) from the top of vertex buffer.</summary>
        public int VertexOffset;
        /// <summary>Base vertex.</summary>
        public int BaseVertex;                

        /// <summary>
        /// Konstruktor.
        /// </summary>
        internal IndexedPrimitivesDrawCall(PrimitiveType primitiveType, Int32 numVertices, Int32 primitiveCount,
            Int32 startIndex, Int32 vertexOffset, Int32 baseVertex)
            : base()
        {
            this.AllowHWInstancing = true;

            this.PrimitiveType = primitiveType;
            this.NumVertices = numVertices;
            this.PrimitiveCount = primitiveCount;
            this.StartIndex = startIndex;
            this.VertexOffset = vertexOffset;
            this.BaseVertex = baseVertex;
        }

        /// <summary>
        /// Metoda vykresli objekt
        /// </summary>
        public override void Render()
        {
            ShevaEngine.Instance.GraphicsDevice.DrawIndexedPrimitives(
                this.PrimitiveType, this.BaseVertex, 0, this.NumVertices, this.StartIndex, this.PrimitiveCount);            
        }

        /// <summary>
        /// Metoda vykresli objekt
        /// </summary>
        public override void RenderHWInstancing(int instancesCount)
        {
            ShevaEngine.Instance.GraphicsDevice.DrawInstancedPrimitives(
                this.PrimitiveType, this.BaseVertex, 0, this.NumVertices, this.StartIndex, this.PrimitiveCount, instancesCount);
        }

        ///// <summary>
        ///// Method clones object.
        ///// </summary>
        ///// <returns></returns>
        //public object Clone()
        //{
        //    IndexedPrimitivesDrawCall newDrawCall = new IndexedPrimitivesDrawCall();

        //    newDrawCall.BaseVertex = this.BaseVertex;
        //    newDrawCall.NumVertices = this.NumVertices;
        //    newDrawCall.PrimitiveCount = this.PrimitiveCount;
        //    newDrawCall.PrimitiveType = this.PrimitiveType;
        //    newDrawCall.StartIndex = this.StartIndex;
        //    newDrawCall.VertexOffset = this.VertexOffset;

        //    return newDrawCall;
        //}
    }

    /// <summary>
    /// IndexedPrimitivesDrawCall equality comparer.
    /// </summary>
    public class IndexedPrimitivesDrawCallEqualityComparer : IEqualityComparer<IndexedPrimitivesDrawCall>
    {
        /// <summary>
        /// Method equals.
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <returns></returns>
        public bool Equals(IndexedPrimitivesDrawCall x, IndexedPrimitivesDrawCall y)
        {
            return 
                x.BaseVertex == y.BaseVertex &&
                x.NumVertices == y.NumVertices &&
                x.PrimitiveCount == y.PrimitiveCount &&
                x.PrimitiveType == y.PrimitiveType &&
                x.StartIndex == y.StartIndex &&
                x.VertexOffset == y.VertexOffset;
        }

        /// <summary>
        /// Get hash code.
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public int GetHashCode(IndexedPrimitivesDrawCall obj)
        {
            return base.GetHashCode();
        }
    }
}
